package threaduse.syn;

/**
 * 三个窗口售票
 */
public class SellTicket {
    public static void main(String[] args) {
        SellTicket01 sellTicket = new SellTicket01();
        SellTicket01 sellTicket1 = new SellTicket01();
        SellTicket01 sellTicket2 = new SellTicket01();

        sellTicket.start();// 启动售票线程
        sellTicket1.start();// 启动售票线程
        sellTicket2.start();// 启动售票线程

//        System.out.println("====使用接口方式====");
//        SellTicket03 sellTicket3 = new SellTicket03();
//        new Thread(sellTicket3).start();
//        new Thread(sellTicket3).start();
//        new Thread(sellTicket3).start();
    }
}

// 使用接口的方式 --- 使用 syn 实现线程同步
class SellTicket03 implements Runnable {
    private int ticketNum = 100; // 是同一个对象 所以不用静态
    // 二阶段死循环后 再加这个代码
    private boolean loop = true;

    public synchronized void sell() { // 在一个时刻 只能进来一个线程
        if (ticketNum <= 0){
            System.out.println("售票结束.....");
            // 二阶段设置
            loop = false;
            return;
        }
        // 休眠 50 毫秒
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("窗口 " + Thread.currentThread().getName() + " 售出一张票 " + " 剩余票数= " + (ticketNum--));
    }

    @Override
    public  void run() { // 方法同步 -- 同一时间只有一个线程进来执行 --- 但是这样就和单线程没区别了
        while (loop){
            sell();
        }
    }

}

class SellTicket01 extends Thread {
    private static int ticketNum = 100; // 线程共享

    // 谁便创建一个对象 --- 用来当锁  先不加 final 加静态的也可以
    static Object object = new Object();

    @Override
    public void run() {
        while (true){
            // 对象上加锁
            synchronized (object){ // 这个锁的必须是同一个对象  这里不能使用 this 因为进来 start() 的不是同一个对象 就是各锁各的
                if (ticketNum <= 0){
                    System.out.println("售票结束.....");
                    break;
                }
                // 休眠 50 毫秒
                try {
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println("窗口 " + Thread.currentThread().getName() + " 售出一张票 " + " 剩余票数= " + (ticketNum--));
            }

        }
    }

}

